using System;
using System.Collections;

namespace WebApplication
{
	[Serializable]
	public class SideCollection : ICollection
	{
		private ArrayList  _aSides;

		public Side this [int index]   // indexer declaration
		{ 
			get
			{
				return (Side) _aSides[index];
			}

			set
			{
				_aSides[index] = value;
			}
		}

		public void CopyTo(Array a, int index)
		{
			_aSides.CopyTo(a, index);
		}
		public object SyncRoot
		{
			get{return this;}
		}
		public bool IsSynchronized
		{
			get{return false;}
		}

		public int Count
		{
			get
			{
				return _aSides.Count;
			}
		}

		public SideCollection ()
		{
			_aSides = new ArrayList ();
		}

		public void Add (System.Object SideCompany)
		{
			_aSides.Add (SideCompany);
		}

		public void Add (Side Side)
		{
			_aSides.Add (Side);
		}

		public void Remove (Side Side)
		{
			_aSides.Remove (Side);
		}

		// IEnumerable Interface Implementation:

		public IEnumerator GetEnumerator() // non-IEnumerable version
		{
			return _aSides.GetEnumerator ();
		}

		IEnumerator IEnumerable.GetEnumerator() // IEnumerable version
		{
			//			return (IEnumerator) new SideEnumerator(this);
			return _aSides.GetEnumerator ();
		}
	}

	[Serializable]
	public class Side
	{
		public enum LetterDirection { A, B, C, D, E, F };
		public enum CompassDirection { N, NW, NE, S, SW, SE };
		public enum LetterOrCompassEnum { Letter, Compass };
		private LetterOrCompassEnum		_letterOrCompass;
		private LetterDirection			_letter;
		private CompassDirection		_compass;

		public string GetDirection ()
		{
			string	sReturn; 

			if (_letterOrCompass == LetterOrCompassEnum.Compass)
			{
				switch (_compass)
				{
					case CompassDirection.N:
					{
						sReturn = "N";
						break;
					}

					case CompassDirection.NE:
					{
						sReturn = "NE";
						break;
					}

					case CompassDirection.NW:
					{
						sReturn = "NW";
						break;
					}

					case CompassDirection.S:
					{
						sReturn = "S";
						break;
					}

					case CompassDirection.SW:
					{
						sReturn = "SW";
						break;
					}
					case CompassDirection.SE:
					{
						sReturn = "SE";
						break;
					}

					default:	// Should never, ever get here.
					{
						sReturn = "Unrecoverable Error";
						break;
					}
				}
			}
			else
			{
				switch (_letter)
				{
					case LetterDirection.A:
					{
						sReturn = "A";
						break;
					}

					case LetterDirection.B:
					{
						sReturn = "B";
						break;
					}

					case LetterDirection.C:
					{
						sReturn = "C";
						break;
					}

					case LetterDirection.D:
					{
						sReturn = "D";
						break;
					}

					case LetterDirection.E:
					{
						sReturn = "E";
						break;
					}

					case LetterDirection.F:
					{
						sReturn = "F";
						break;
					}

					default:	// Should never, ever get here.
					{
						sReturn = "Error";
						break;
					}
				}
			}
		
			return sReturn;
		}

		public bool SetDirection (string sDirection)
		{
			bool bReturn = true;  // true indicates success

			switch (sDirection)
			{
				case "N":
				{
					_compass = CompassDirection.N;
					_letterOrCompass = LetterOrCompassEnum.Compass;
					break;
				}

				case "NE":
				{
					_compass = CompassDirection.NE;
					_letterOrCompass = LetterOrCompassEnum.Compass;
					break;
				}
				case "NW":
				{
					_compass = CompassDirection.NW;
					_letterOrCompass = LetterOrCompassEnum.Compass;
					break;
				}
				case "S":
				{
					_compass = CompassDirection.S;
					_letterOrCompass = LetterOrCompassEnum.Compass;
					break;
				}
				case "SW":
				{
					_compass = CompassDirection.SW;
					_letterOrCompass = LetterOrCompassEnum.Compass;
					break;
				}
				case "SE":
				{
					_compass = CompassDirection.SE;
					_letterOrCompass = LetterOrCompassEnum.Compass;
					break;
				}

				case "A":
				{
					_letter = LetterDirection.A;
					_letterOrCompass = LetterOrCompassEnum.Letter;
					break;
				}

				case "B":
				{
					_letter = LetterDirection.B;
					_letterOrCompass = LetterOrCompassEnum.Letter;
					break;
				}

				case "C":
				{
					_letter = LetterDirection.C;
					_letterOrCompass = LetterOrCompassEnum.Letter;
					break;
				}

				case "D":
				{
					_letter = LetterDirection.D;
					_letterOrCompass = LetterOrCompassEnum.Letter;
					break;
				}

				case "E":
				{
					_letter = LetterDirection.E;
					_letterOrCompass = LetterOrCompassEnum.Letter;
					break;
				}

				case "F":
				{
					_letter = LetterDirection.F;
					_letterOrCompass = LetterOrCompassEnum.Letter;
					break;
				}

				default:	// Should never, ever get here.
				{
					GameException	e; 
					e = new GameException ("Error:  Illegal direction.  Side.cs");
					throw (e);
				}
			}

			return bReturn;
		}

		public LetterOrCompassEnum LetterOrCompass
		{
			get { return _letterOrCompass; }
			set { _letterOrCompass = value; }
		}

		public LetterDirection Letter
		{
			get { return _letter; }
			set { _letter = value; }
		}

		public CompassDirection Compass
		{
			get { return _compass; }
			set { _compass = value; }
		}

		public Side()
		{
		}

		public void ConvertToCompassWithRotation (Side oldSide, int rotation)  // A = South, B = Southwest, C = Northwest, etc...  rotation 0, 60, 120, 240, or 300.
		{
			this.LetterOrCompass = LetterOrCompassEnum.Compass;
			rotation = rotation / 60;
			string	sDirection = oldSide.GetDirection ();
			int nDirection = sDirection[0] - 'A';  // Will this work.
			nDirection += rotation;
			nDirection %= 6;  // Modulus operation.

			switch (nDirection)
			{
				case 0:
					this.Compass = CompassDirection.S;
					break;

				case 1:
					this.Compass = CompassDirection.SW;
					break;

				case 2:
					this.Compass = CompassDirection.NW;
					break;

				case 3:
					this.Compass = CompassDirection.N;
					break;

				case 4:
					this.Compass = CompassDirection.NE;
					break;

				case 5:
					this.Compass = CompassDirection.SE;
					break;

				default:

					break;

			}
		}
	}
}
